package org.kl.bf.service.basic;

import java.sql.Timestamp;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;
import org.kl.bf.entity.basic.Calendar;
import org.kl.bf.entity.basic.CalendarType;
import org.kl.bf.entity.basic.User;
import org.kl.bf.repository.basic.CalendarDao;
import org.kl.bf.repository.basic.CalendarTypeDao;
import org.kl.bf.repository.basic.UserDao;
import org.kl.bf.service.ServiceException;
import org.kl.bf.utils.BasicConstants;
import org.kl.bf.utils.CRUDUtils;
import org.kl.bf.utils.KLDynamicSpecifications;
import org.kl.bf.utils.KLSearchFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;

/**
 * @Author hqm
 * @CreateTime 2014-3-13 下午9:11:30
 */
// Spring Bean的标识.
@Component
// 默认将类中的所有public函数纳入事务管理.
@Transactional
public class CalendarService {

	private CalendarDao calendarDao;
	private CalendarTypeDao calendarTypeDao;
	private UserDao userDao;

	public Calendar getCalendar(String guid) {
		return calendarDao.find(Calendar.class, guid);
	}

	public void saveCalendar(Calendar entity) {
		calendarDao.save(entity);
	}

	public void deleteCalendar(String guid) {
		calendarDao.delete(guid);
	}

	public List<Calendar> getCalendarListBytypeId(String typeId, String userId) {
		return calendarDao.findByCalendarTypeIdAndUserId(typeId, userId);
	}

	/**
	 * 删除多条记录
	 * 
	 * @param ids
	 */
	public String multiDelete(String ids) {
		String[] idArray = StringUtils.split(ids, ",");
		int i = 0;
		for (String id : idArray) {
			if (StringUtils.isNotBlank(id)) {
				calendarDao.delete(id);
				i++;
			}
		}
		return "删除" + i + "条记录";
	}

	/**
	 * 生成系统提醒日程
	 * 
	 * @param userName
	 *            用户姓名集合，字符串，多个用“;”隔开
	 * @param title
	 * @param allDay
	 * @param start
	 * @param end
	 * @return
	 */
	public void buildSystemWarnCalendar(String userNames, String title, boolean allDay, Timestamp start, Timestamp end) {
		if (StringUtils.isBlank(userNames)) {
			throw new ServiceException("用户名称不能为空，无法生成日程");
		}
		String[] userNameArray = StringUtils.split(userNames, ";");
		for (String userName : userNameArray) {
			User user = userDao.findByTrueName(userName);
			if (user == null) {
				throw new ServiceException("无法找到用户" + userName + "生成日程失败");
			}

			CalendarType calendarType = calendarTypeDao.findByUserIdAndTypeName(user.getId(),
					BasicConstants.warnerCalendarType.getTypeName());
			if (calendarType == null) {
				calendarType = new CalendarType();
				calendarType.setUser(user);
				calendarType.setBackgroundColor(BasicConstants.warnerCalendarType.getBackgroundColor());
				calendarType.setTypeName(BasicConstants.warnerCalendarType.getTypeName());
				calendarTypeDao.save(calendarType);
			}
			Calendar calendar = new Calendar();
			calendar.setCalendarType(calendarType);
			calendar.setBackgroundColor(calendarType.getBackgroundColor());
			calendar.setUser(user);
			calendar.setTitle(title);
			calendar.setAllDay(allDay ? 1 : 0);
			calendar.setEditable(1);
			calendar.setStart(start);
			calendar.setEnd(end);
			calendarDao.save(calendar);
		}
	}

	public List<Calendar> getAllCalendar() {
		return calendarDao.findAll();
	}

	public List<Calendar> getCalendarListBystartGreaterThan(final Timestamp startTime, final String userId) {
		return calendarDao.findAll(new Specification<Calendar>() {
			@SuppressWarnings({ "unchecked", "rawtypes" })
			@Override
			public Predicate toPredicate(Root<Calendar> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				List<Predicate> predicates = Lists.newArrayList();
				predicates.add(builder.greaterThanOrEqualTo((Path) root.get("end"), (Comparable) startTime));
				predicates.add(builder.equal((Path) root.get("user").get("id"), userId));
				// 将所有条件用 and 联合起来
				return builder.and(predicates.toArray(new Predicate[predicates.size()]));
			}
		});
	}

	public Page<Calendar> getUserCalendar(Map<String, Object> searchParams, int pageNumber, int pageSize, String sortType, String orderType) {
		PageRequest pageRequest = CRUDUtils.buildPageRequest(pageNumber, pageSize, sortType, orderType);
		Specification<Calendar> spec = buildSpecification(searchParams);

		return calendarDao.findAll(spec, pageRequest);
	}

	/**
	 * 创建动态查询条件组合.
	 */
	private Specification<Calendar> buildSpecification(Map<String, Object> searchParams) {
		Map<String, KLSearchFilter> filters = KLSearchFilter.parse(searchParams);
		Specification<Calendar> spec = KLDynamicSpecifications.byKLSearchFilter(filters.values(), Calendar.class);
		return spec;
	}

	@Autowired
	public void setCalendarDao(CalendarDao calendarDao) {
		this.calendarDao = calendarDao;
	}

	@Autowired
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	@Autowired
	public void setCalendarTypeDao(CalendarTypeDao calendarTypeDao) {
		this.calendarTypeDao = calendarTypeDao;
	}

}
